package com.sz.common.core.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sz.common.base.constants.OperationLevel;
import com.sz.common.base.logger.Logger;

import com.sz.common.core.constants.ModuleNames;
import com.sz.common.core.service.queue.Queue;
import com.sz.common.core.service.queue.Queues;
import com.sz.common.core.system.entity.OperationLog;
import com.sz.common.base.constants.UserActions;

import java.util.Map;

/**
 * Function: PrincipalLogUtils <br>
 * Author: Charles <br>
 * Date: 2016-11-22 14:59:00
 */
public class PrincipalLogUtils {

    private static Logger logger = Logger.getLogger(PrincipalLogUtils.class);

    /**
     * 添加操作日志.
     *
     * @param moduleName 模块名称，可选，参考{@link ModuleNames}及其派生类
     * @param subModule  子模块名称，可选，参考{@link ModuleNames}及其派生类
     * @param action     action, 可选，参考{@link UserActions}
     * @param operation  操作日志
     */
    public static void addOperationLog(String moduleName, String subModule, String action, String operation) {
        addOperationLog(moduleName, subModule, action, operation, null, OperationLevel.NORMAL);
    }

    /**
     * 添加操作日志及数据备份.
     *
     * @param moduleName 模块名称，可选，参考{@link ModuleNames}及其派生类
     * @param subModule  子模块名称，可选，参考{@link ModuleNames}及其派生类
     * @param action     action, 可选，参考{@link UserActions}
     * @param operation  操作日志
     * @param dataBackup 数据备份
     */
    public static void addOperationLog(String moduleName, String subModule, String action, String
            operation, Map<String, Object> dataBackup) {
        addOperationLog(moduleName, subModule, action, operation, dataBackup, OperationLevel.CRITICAL);
    }

    /**
     * 添加操作日志及数据备份.
     *
     * @param moduleName 模块名称，可选，参考{@link ModuleNames}及其派生类
     * @param subModule  子模块名称，可选，参考{@link ModuleNames}及其派生类
     * @param action     action, 可选，参考{@link UserActions}
     * @param operation  操作日志
     * @param dataBackup 数据备份
     * @param level      重要级别
     *                   1:normal(一般型日志),可能被自动清除
     *                   2:important(重要日志),可以手动删除
     *                   3:critical(永久留存), 不能删除
     *                   参考{@link OperationLevel}
     */
    public static void addOperationLog(String moduleName, String subModule, String action, String
            operation, Map<String, Object> dataBackup, int level) {

        if (operation == null || operation.trim().length() == 0) {
            throw new IllegalArgumentException("operation cannot be empty!");
        }
        String jsonDataBackup = null;
        if (dataBackup != null) {
            ObjectMapper mapper = new ObjectMapper();
            try {
                jsonDataBackup = mapper.writeValueAsString(dataBackup);
            } catch (JsonProcessingException e) {
                logger.error("error occurred when convert backup data to json", e);
                throw new RuntimeException(e);
            }
        }

        Principal principal = PrincipalUtils.tryToGetPrincipal();
        OperationLog log = new OperationLog();
        log.setAccountId(principal == null ? 0 : principal.getAccountId());
        log.setDomainId(principal == null ? 0 : principal.getDomainId());
        log.setModule(moduleName);
        log.setSubModule(subModule);
        log.setAction(action);
        log.setOperation(operation);
        log.setDataBackup(jsonDataBackup);
        log.setUserIP(principal == null ? "0.0.0.0":principal.getIpAddr());
        log.setLevel(level);
        log.setDescription(null);

        getQueue().add(log);
    }

    private static Queue<OperationLog> queue;

    private static Queue<OperationLog> getQueue() {
        if (queue == null) {
            queue = Queues.getPrincipalLogsQueue();
        }
        return queue;
    }
}
